Skip to content

fix(voice): keep Realtime handoff audio and prevent hangup errors - #318

Merged
johnmatthewtennant merged 13 commits into
mainfrom
codex/realtime-cancellation-race
Sep 22, 2026
Merged

johnmatthewtennant merged 13 commits into
mainfrom
codex/realtime-cancellation-race

Conversation

@johnmatthewtennant

@johnmatthewtennant johnmatthewtennant commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Context

In OpenAI Realtime Expert-Spokesperson calls, the spokesperson can begin a spoken acknowledgement and invoke the handoff tool in the same response. Berd treated that handoff as a cancellation of the response that produced it, marking its own acknowledgement interrupted. OpenAI could then report that the already-finished response was no longer active and terminate the call.

Normal hangup could also stop the native runtime before already-queued provider events reached it, surfacing Spokesperson runtime is unavailable during teardown.

Summary

A handoff starts Expert work without cancelling acknowledgement audio that has already begun. Once the acknowledgement finishes generating, the Expert response can start while its audio drains. Expert audio replaces any remaining acknowledgement without overlapping it. User speech still interrupts playback immediately.

The provider's late Cancellation failed: no active response found race no longer ends the call.

Hangup drains provider events that were already queued before stopping the native runtime, preventing a late teardown event from surfacing as a call failure.

Reviewer-reproducible example

  1. Run just dev, configure Voice for OpenAI Realtime Expert-Spokesperson, start a voice call, and mute the microphone.
  2. Ask the Spokesperson to use the terminal to run pwd and report the printed path. The wording can vary; the request must require Expert tool use and produce a handoff.
  3. Confirm the acknowledgement becomes Spoken and the Spokesperson → Expert · Handoff event appears without marking the acknowledgement Interrupted.
  4. Let the Expert answer arrive. Confirm its audio replaces any remaining acknowledgement rather than overlapping it.
  5. Start another acknowledgement, unmute the microphone, speak while it is playing, and confirm user speech interrupts it immediately.
  6. Mute the microphone, repeat the pwd tool-use request, wait for the handoff event, then hang up. Confirm the call returns to its normal start state without either cancellation error or Spokesperson runtime is unavailable.

Track coordinator cancellation requests and consume correlated no-active-response errors before forwarding provider events to the host. Preserve fatal handling for unrelated and unexpected errors.

Validation: Blox jtennant-berd-cancel-race-20260910 at base 5d5708e; 256 voice library tests and 24 protocol tests passed, plus just fmt-check, check, tauri-check, and clippy. Local changed file is byte-identical to the validated tree (SHA-256 2cf53b9b7e542ccc73e935627d69e26fb18d0c1e2fb0b15afcf48a7e45e0c0a5). Supplemental all-targets Clippy diagnostics also reproduce on unchanged main.
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant johnmatthewtennant changed the title fix(voice): keep Realtime calls alive after cancellation races fix(voice): preserve Realtime handoff preambles Sep 22, 2026
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant johnmatthewtennant changed the title fix(voice): preserve Realtime handoff preambles fix(voice): prevent handoffs from cancelling preamble audio Sep 22, 2026
* origin/main:
  refactor(voice): rename berd-voice to berd-call (#338)
  docs: warn about bb-cli migration (#337)
  feat(voice): play status cues while working or waiting (#308)
  chore: bump goose backend pin to 2c02ed6f (#331)
  fix(windows): never resolve Git Bash to the WSL or Store bash.exe stubs (#328)
  fix(windows): keep the Windows script tests runnable on Windows PowerShell 5.1 (#329)
  chore: bump goose backend pin to 616cdce9 (#330)
  feat(chat): add starred models to the agent model picker (#287)
  chore: bump goose backend to 51d9effe (#325)
  fix(chat): collapse labeled monitor updates (#324)
  default project chats to a saved SSH environment (#323)

Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant

Copy link
Copy Markdown
Contributor Author

🤖 User-observed Realtime lifecycle bug from live testing: ending an Expert-Spokesperson call displayed Spokesperson runtime is unavailable. This appears to be a clean-shutdown ordering issue rather than evidence that the active call failed: the renderer intentionally enters stopping while final runtime events are still draining, so a late runtime failure can be surfaced after shutdown has begun. Please ensure intentional stop suppresses or classifies that late failure without hiding genuine failures before shutdown.

* origin/main:
  fix(voice): keep status cues subordinate to speech (#339)

Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant johnmatthewtennant changed the title fix(voice): prevent handoffs from cancelling preamble audio fix(voice): preserve Realtime handoffs and graceful shutdown Sep 22, 2026
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant johnmatthewtennant changed the title fix(voice): preserve Realtime handoffs and graceful shutdown fix(voice): keep Realtime handoff audio and prevent hangup errors Sep 22, 2026
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant
johnmatthewtennant marked this pull request as ready for review September 22, 2026 21:31
@johnmatthewtennant
johnmatthewtennant requested a review from a team September 22, 2026 21:31

@morgmart morgmart left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated code review

Engineering review found no publishable findings in the exact PR comparison. The changed voice-call lifecycle, cancellation correlation, transcript discard handling, shutdown ordering, and regression tests are internally consistent under static inspection. Supplied GitHub checks are complete and successful. Recommend APPROVE.

Deterministic publication result: 0 blocking and 0 non-blocking inline finding(s) publishable; 0 duplicate(s) suppressed; 0 blocking screenshot-evidence requirement(s) in this review body.

Pending checks: 1 check(s) are not complete.

This approval reflects the completed code review only; merge readiness remains governed by the repository's required checks.

@johnmatthewtennant
johnmatthewtennant merged commit 784cf89 into main Sep 22, 2026
10 checks passed
@johnmatthewtennant
johnmatthewtennant deleted the codex/realtime-cancellation-race branch September 22, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants